extends Node2D
@export var spread_curve: Curve
@export var y_curve: Curve
@export var rotation_curve: Curve
@export var card_select_mode: bool = false

@onready var card_talbe = get_parent()

signal organize_cards(discard: bool, select: bool, preview: bool, which_card_ui: CardView)

var card_in_preview: CardView
var card_in_select: CardView


func _ready():
	organize_cards.connect(_on_organize_cards)
	if card_select_mode:
		position = Vector2(get_viewport_rect().size.x / 2, 250)
	else:
		position = Vector2(get_viewport_rect().size.x / 2, get_viewport_rect().size.y - 150)
	Events.card_table_card_info_update.connect(_on_card_table_card_info_update)


func _on_card_table_card_info_update():
	for card_view in get_children():
		card_view.update_label()


func add(card_view: CardView):
	card_view.card_container = self
	add_child(card_view)
	do_organize_cards()


func has_card(card_view):
	for c in get_children():
		if c == card_view:
			return true
	return false


func _on_organize_cards(discard: bool, select: bool, preview: bool, card_view: CardView):
	if discard:
		if card_select_mode:
			return
		card_in_preview = null
		card_in_select = null
		card_discard(card_view, card_talbe.get_node("DiscardPoll").global_position)
		card_talbe.arrow.startPos = null
		card_talbe.arrow.hide()
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
		return

	if preview:
		if card_in_preview != null:
			#如果mouse on的时候发现有已经有preview的牌，那么需要执行preview牌的end touch方法。
			#（是因为CollisionShape2D重叠时都会发出mouse on信号，所以这里为了处理这种情况）
			card_in_preview._on_mask_mouse_exited()
			pass
		card_in_preview = card_view
	else:
		card_in_preview = null

	if select:
		card_in_select = card_view
		print("选卡:", card_in_select.card.card_id)
		Events.card_aim_started.emit(card_in_select)
	else:
		card_in_select = null
		Events.card_aim_ended.emit(card_in_select)
	do_organize_cards()


func do_organize_cards():
	var cards = get_children()
	var card_count = cards.size()

	for card: CardView in cards:
		var hand_card_index = cards.find(card)
		var hand_radio = 0.5
		if card_count <= 0:
			return
		# 将卡牌的hand_radio值做“归一化”处理，输出0...1的均值，无论有多少张卡
		if card_count == 1:
			hand_radio = 0.5
		else:
			hand_radio = float(hand_card_index) / float(card_count - 1)
		# 对每张卡片进行调整以形成扇形
		var spread = 70
		if card_count > 12:
			@warning_ignore("integer_division")
			spread = int(840 / card_count)
		var x = spread_curve.sample(hand_radio) * card_count * spread
		var y = -y_curve.sample(hand_radio) * card_count * 8
		var rotation_fix = rotation_curve.sample(hand_radio) * card_count * 0.03

		if card_in_preview != null:
			var card_in_preview_index = cards.find(card_in_preview)
			var index_offset = abs(hand_card_index - card_in_preview_index)
			var base = 2  # 调整这个值以控制指数递减的速度
			var correction = 200 * pow(base, -index_offset)
			# 对预览卡牌两侧的卡做一个指数递减的横向偏移
			if card_in_preview_index > hand_card_index:
				x -= correction
			elif card_in_preview_index < hand_card_index:
				x += correction

		if card_in_select != null:
			y = y + 20
			card.mask.visible = false
		else:
			card.mask.visible = true

		card.update_transform(rotation_fix, Vector2(x, y), Vector2(x, -80))


# 删除一张牌
func card_discard(card_view: CardView, target_pos: Vector2):
	var cards = get_children()
	if cards.size() > 0:
		if card_view.tween:
			card_view.tween.kill()  # 终止之前的补间动画。
		card_view.tween = card_view.create_tween()
		var tween: Tween = card_view.tween
		tween.set_parallel()
		
		if card_view.card.once:
			tween.tween_property(card_view, "scale", Vector2(0, 0), 0.15)
		else:
			tween.tween_property(card_view, "scale", Vector2(0, 0), 0.15)
			tween.tween_property(card_view, "global_position", target_pos, 0.15)
		tween.play()
		await tween.finished
		remove_child(card_view)
		card_view.queue_free()
		do_organize_cards()


func recovery_player_card():
	for card_view in get_children():
		var s: CardState = card_view.card_state_machine.current_state
		s.transition_requested.emit(s, CardState.State.STATE_DISCARD)


func clear_card():
	for card_view in get_children():
		card_view.queue_free()


func get_all_card() -> Array:
	return get_children()
	

func can_use_card():
	for card_view in get_children():
		card_view.can_use = true
	
func cant_use_card():
	for card_view in get_children():
		card_view.can_use = false
